package com.example.order.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.order.service.StockFeignService;
import com.example.order.exception.BlockExceptionHandler;
import com.example.order.service.OrderFeignService;
import com.example.order.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description TODO
 * @Author JFeng
 * @Date 2024/4/19
 */

@RestController
@RequestMapping("/order")
@RefreshScope // 修改配置中心的配置后，会刷新配置
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderFeignService orderFeignService;

    @Autowired
    private StockFeignService stockFeignService;

    @Autowired
    private UserService userService;

    @Value("${server.port}")
    private String port;


    @RequestMapping("/add")
    public Object add() throws InterruptedException {
//        TimeUnit.SECONDS.sleep(2); // 模拟慢调用

        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("RequestMapping", "/add生成订单");
        map.put("port", port);
        return JSONUtil.toJsonStr(map);
    }

    /**
     * 测试流控规则中的关联，系统流量较大时：
     * 让生成订单资源(/add)触发查询订单资源(/get)的限流
     * 给查询订单设置流控规则，关联生成订单资源。
     *
     * @return
     */
    @RequestMapping("/get")
    public Object get() {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("RequestMapping", "/get查询订单");
        map.put("port", port);
        return JSONUtil.toJsonStr(map);
    }

    @RequestMapping("/getById/{id}")
    @SentinelResource(value = "getById",
            blockHandlerClass = BlockExceptionHandler.class,
            blockHandler = "blockHandlerGetById"
    )
    public Object getById(@PathVariable String id) {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("RequestMapping", "/getById查询订单");
        map.put("port", port);
        map.put("id", id);
        return JSONUtil.toJsonStr(map);
    }


    @RequestMapping("/add2/{num}")
    public Object add2(@PathVariable Long num) {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("port", port);
        if (10 == num) {
            // 模拟异常
            Long a = null;
            if (9l == a) { // 会把a拆箱再比较.a为null时拆箱会抛空指针异常

            }
//            int a = 0 / 0;
        }
        map.put("num", num);
        map.put("RequestMapping", "/add2");

        return JSONUtil.toJsonStr(map);
    }

    @RequestMapping("/entrance1")
    public Object entrance1() {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("port", port);
        map.put("RequestMapping", "/entrance1");
        map.put("user", userService.getUser());
        String response = orderFeignService.add();
        map.put("response", response);
        return JSONUtil.toJsonStr(map);
    }

    @RequestMapping("/entrance2")
    public Object entrance2() {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("port", port);
        map.put("RequestMapping", "/entrance2");
        map.put("user", userService.getUser());
        String response = orderFeignService.add();
        map.put("response", response);
        return JSONUtil.toJsonStr(map);
    }


    @RequestMapping("/testFeignFusing")
    public Object testFeignFusing() {
        Map<Object, Object> map = new HashMap<>();
        map.put("orderService", UUID.fastUUID().toString());
        map.put("port", port);
        map.put("RequestMapping", "/testFeignFusing");
        String response = stockFeignService.reduce(10);
        map.put("response", response);
        return JSONUtil.toJsonStr(map);
    }
}
